﻿using System.Collections.Generic;
using System.Linq;
using DataAccessLayer;

namespace Editor
{
    public sealed class EnemyPresenter : IEnemyPresenter
    {
        private readonly IPresenterFacade Parent;

        public List<NormalEnemy> Model { get; set; }

        public EnemyPresenter(IPresenterFacade parent)
        {
            Parent = parent;

            Model = new List<NormalEnemy>();
        }

        public NormalEnemy AddEnemy()
        {
            int id = Parent.CreateObjectId();

            NormalEnemy enemy = new NormalEnemy { ID = id };

            Model.Add(enemy);

            return enemy;
        }

        public Enemy GetEnemy(int id)
        {
            return Model.Single(enemy => enemy.ID == id);
        }

        public void SetEnemySprite(int id, string spriteName)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));

            Model[index].TextureName = spriteName;
        }

        public void SetSourceRectangle(int id, EditorRect srRect)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));

            Model[index].SourceRect = srRect;
        }

        public EditorRect SetCollisionRectangle(int id, EditorRect colRect)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));

            Model[index].CollisionRectangle = colRect;

            return Model[index].CollisionRectangle;
        }

        public bool AddWeapons(int id, IEnumerable<int> weaponIds, out string errMsg)
        {
            int index = Model.IndexOf(Model.Single(prot => prot.ID == id));

            List<WeaponBase> weapons = Parent.GetWeapons();

            IEnumerable<WeaponBase> selectedWeapons = from wpn in weapons
                                                     from wpnId in weaponIds
                                                     where wpn.ID == wpnId
                                                     select wpn;

            IEnumerable<WeaponBase> enemyWeapons = (from wpn in weapons
                                                       from wpnId in Model[index].WeaponIds
                                                       where wpn.ID == wpnId
                                                       select wpn);

             errMsg = "";

            int selectedWeaponsTotalSlots = selectedWeapons.Sum(wpn => wpn.RequiredSlots);
            if (Model[index].WeaponSlots < selectedWeaponsTotalSlots &&
                 enemyWeapons.Sum(wpn => wpn.RequiredSlots) + selectedWeaponsTotalSlots < Model[index].WeaponSlots)
            {
                Model[index].WeaponIds.AddRange(weaponIds);

                return true;
            }

            errMsg = "Enemy does not have enough weapon slots.";

            return false;
        }

        public void SaveData(int id, int hp, int power, int speed, int weaponSlots)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));

            Model[index].Hp = hp;
            Model[index].Power = power;
            Model[index].Speed = speed;
            Model[index].WeaponSlots = weaponSlots;
        }

        public void SaveData(int id, AircraftStats stats, SinglecRectProperties rects)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));

            Model[index].Hp = stats.Hp;
            Model[index].Power = stats.Power;
            Model[index].Speed = stats.Speed;
            Model[index].WeaponSlots = stats.WeaponSlots;

            Model[index].SourceRect = rects.SourceRectangle;
            Model[index].CollisionRectangle = rects.CollisionRectangle;
        }

        public void DeleteEnemy(int id)
        {
            int index = Model.IndexOf(Model.Single(enemy => enemy.ID == id));
    
            Model.RemoveAt(index);
        }
    }
}